package cytargetlinker.conversion.data;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.bridgedb.DataSource;
import org.bridgedb.IDMapper;
import org.bridgedb.IDMapperException;
import org.bridgedb.Xref;

import cytargetlinker.conversion.graph.Graph;
import cytargetlinker.conversion.graph.Graph.Node;

public class TFNode implements INode {

	private String id;
	private List<String> ncbiGene;
	private List<String> uniprot;
	private String label;
	private String biologicalType = "transcriptionFactor";
	private String tfFamily = "";
	
	private TFNode(String ensembl) {
		this.id = ensembl;
		ncbiGene = new ArrayList<String>();
		uniprot = new ArrayList<String>();
	}
	
	public static TFNode createGeneNode(String id, String name, IDMapper mapper, DataSource in, String tfFamily) {
		// get ensembl identifier
		Xref ensembl;
		if(in.equals(DataSource.getBySystemCode("En"))) {
			ensembl = new Xref(id, in);
		} else {
			Xref xrefIn = new Xref(id, in);
			try {
				Set<Xref> ens = mapper.mapID(xrefIn, DataSource.getBySystemCode("En"));
				if(!ens.isEmpty()) {
					ensembl = ens.iterator().next();
				} else {
					return null;
				}
			} catch (IDMapperException e) {
				return null;
			}
		}
		
		TFNode node = new TFNode(ensembl.getId());
		if(tfFamily != null) node.setTfFamily(tfFamily);
		node.setLabel(name);
		
		// get all ncbi gene identifiers mapped to the ensembl identifier
		try {
			Set<Xref> result = mapper.mapID(ensembl, DataSource.getBySystemCode("L"));
			for(Xref x : result) {
				String ncbigene = x.getId();
				if(!node.getNcbiGene().contains(ncbigene)) node.getNcbiGene().add(ncbigene);
			}
		} catch (IDMapperException e) {
		}
		
		// get all uniprot identifiers mapped to the ensembl identifier
		try {
			Set<Xref> result = mapper.mapID(ensembl, DataSource.getBySystemCode("S"));
			for(Xref x : result) {
				String uniprot = x.getId();
				if(!node.getUniprot().contains(uniprot)) node.getUniprot().add(uniprot);
			}
		} catch (IDMapperException e) {
		}
		
		return node;
	}

	public Node getNode(Graph graph) {
		Node node = graph.addNode(getId());
		node.appendAttribute("ensembl", getId());
		node.appendAttribute("identifiers", getIdentifiers());
		node.appendAttribute("label", getLabel());
		node.appendAttribute("name", getLabel());
		node.appendAttribute("biologicalType", getBiologicalType());
		if(!tfFamily.equals("")) node.setAttribute("tf-family", getTfFamily());
		return node;
	}
	
	/**
	 * creates Cytoscape list attribute containing
	 * all identifiers representing this gene
	 */
	private String getIdentifiers() {
		String ids = "[";
		ids = ids + getId();
		
		for(String name : getNcbiGene()) {
			ids = ids + "," + name;
		}
		
		for(String name : getUniprot()) {
			ids = ids + "," + name;
		}
		
		ids = ids + "]";
		return ids;
	}

	// SETTERS & GETTERS
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public List<String> getNcbiGene() {
		return ncbiGene;
	}
	public String getLabel() {
		return label;
	}
	public void setLabel(String label) {
		this.label = label;
	}
	public String getBiologicalType() {
		return biologicalType;
	}
	public List<String> getUniprot() {
		return uniprot;
	}
	public String getTfFamily() {
		return tfFamily;
	}
	public void setTfFamily(String tfFamily) {
		this.tfFamily = tfFamily;
	}
}
